package com.mall.order.services;

import com.mall.commons.result.AbstractResponse;
import com.mall.order.OrderCoreService;
import com.mall.order.biz.TransOutboundInvoker;
import com.mall.order.biz.context.AbsTransHandlerContext;
import com.mall.order.biz.factory.OrderProcessPipelineFactory;
import com.mall.order.constant.OrderRetCode;
import com.mall.order.constants.OrderConstants;
import com.mall.order.dal.entitys.Item;
import com.mall.order.dal.entitys.Order;
import com.mall.order.dal.entitys.OrderItem;
import com.mall.order.dal.entitys.Stock;
import com.mall.order.dal.persistence.*;
import com.mall.order.dto.*;
import com.mall.order.utils.ExceptionProcessorUtils;
import com.mall.user.constants.SysRetCodeConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 *  cskaoyan
 */
@Slf4j
@Component
@Service(cluster = "failfast")
public class OrderCoreServiceImpl implements OrderCoreService {

	@Autowired
	OrderMapper orderMapper;

	@Autowired
	OrderItemMapper orderItemMapper;

	@Autowired
	OrderShippingMapper orderShippingMapper;

	@Autowired
    OrderProcessPipelineFactory orderProcessPipelineFactory;

	@Autowired
	StockMapper stockMapper;

	/**
	 * 创建订单的处理流程
	 *
	 * @param request
	 * @return
	 */
	@Override
	public CreateOrderResponse createOrder(CreateOrderRequest request) {
		CreateOrderResponse response = new CreateOrderResponse();
		try {
			//创建pipeline对象
			TransOutboundInvoker invoker = orderProcessPipelineFactory.build(request);

			//启动pipeline
			invoker.start(); //启动流程（pipeline来处理）

			//获取处理结果
			AbsTransHandlerContext context = invoker.getContext();

			//把处理结果转换为response
			response = (CreateOrderResponse) context.getConvert().convertCtx2Respond(context);
		} catch (Exception e) {
			log.error("OrderCoreServiceImpl.createOrder Occur Exception :" + e);
			ExceptionProcessorUtils.wrapperHandlerException(response, e);
		}
		return response;
	}



	@Override
	@Transactional
	public CancelOrderResponse cancelOrder(CancelOrderRequest request) {
		CancelOrderResponse response = new CancelOrderResponse();
		try {
			request.requestCheck();

			Order order = new Order();
			order.setCloseTime(new Date());
			order.setStatus(OrderConstants.ORDER_STATUS_TRANSACTION_CANCEL);
			order.setOrderId(request.getOrderId());
			orderMapper.updateByPrimaryKeySelective(order);

			List<OrderItem> orderItems = orderItemMapper.queryByOrderId(request.getOrderId());
			for (OrderItem orderItem : orderItems) {
				Integer num = orderItem.getNum();
				Stock stock = stockMapper.selectStock(orderItem.getItemId());
				stock.setLockCount(stock.getLockCount() - num);
				stock.setStockCount(stock.getStockCount() + num);
				stockMapper.updateStock(stock);

				orderItem.setStatus(2);
				orderItemMapper.updateByPrimaryKey(orderItem);
			}
			response.setCode(OrderRetCode.SUCCESS.getCode());
			response.setMsg(OrderRetCode.SUCCESS.getMessage());
		}catch (Exception e){
			log.error("com.mall.order.services.OrderCoreServiceImpl occur Exception :"+ e);
			ExceptionProcessorUtils.wrapperHandlerException(response,e);
		}
		return response;
	}

	@Override
	public DeleteOrderResponse deleteOrder(DeleteOrderRequest request) {
		DeleteOrderResponse response = new DeleteOrderResponse();
		try {
			request.requestCheck();
			orderMapper.deleteByPrimaryKey(request.getOrderId());

			orderShippingMapper.deleteByPrimaryKey(request.getOrderId());

			orderItemMapper.deleteByOrderId(request.getOrderId());

			response.setCode(OrderRetCode.SUCCESS.getCode());
			response.setMsg(OrderRetCode.SUCCESS.getMessage());
		}catch (Exception e){
			log.error("com.mall.order.services.OrderCoreServiceImpl occur Exception :"+ e);
			ExceptionProcessorUtils.wrapperHandlerException(response,e);
		}
		return response;

	}

	@Override
	public UpdateOrderResponse updateOrder(long orderId) {
		UpdateOrderResponse updateOrderResponse = new UpdateOrderResponse();
		try {
			Order order = new Order();
			order.setStatus(7);
			int i = orderMapper.updateByPrimaryKey(order);
			updateOrderResponse.setCode(OrderRetCode.SUCCESS.getCode());
			updateOrderResponse.setMsg(OrderRetCode.SUCCESS.getMessage());
			updateOrderResponse.setAffectedRow(i);
		}catch (Exception e) {
			log.error("com.mall.order.services.OrderCoreServiceImpl.updateOrder occur Exception :"+ e);
			ExceptionProcessorUtils.wrapperHandlerException(updateOrderResponse,e);
		}
		return updateOrderResponse;

	}

}
